﻿using System;
using System.Collections.Generic;
using System.Text;

namespace HZY.Logic.Sys
{
    using System.Linq;
    using System.Threading.Tasks;
    using System.Collections;
    using HZY.DbExtensions;
    using HZY.Models.Sys;
    using HZY.Models;
    using HZY.Toolkit;
    using HZY.DTO.Sys;
    using HZY.Logic.Core;
    using HzySql.Interface;

    public class Sys_UserLogic : LogicBase
    {
        public Sys_UserLogic(HzySqlDbContext dbContext)
            : base(dbContext)
        {

        }

        #region CURD 基础

        /// <summary>
        /// 获取数据源
        /// </summary>
        /// <param name="Page"></param>
        /// <param name="Rows"></param>
        /// <param name="sysUser"></param>
        /// <returns></returns>
        public async Task<TableViewModel> FindListAsync(int Page, int Rows, Sys_User Search)
        {
            var query = db.Query<Sys_User>()
                .Where(w => w.t1.User_Name.Contains(Search.User_Name), !string.IsNullOrEmpty(Search?.User_Name))
                .Where(w => w.t1.User_LoginName.Contains(Search.User_LoginName), !string.IsNullOrEmpty(Search?.User_LoginName))
                .Select(w => new
                {
                    w.t1.User_Name,
                    w.t1.User_LoginName,
                    w.t1.User_Email,
                    当前角色 = w.HzySql($@"
        STUFF((
              SELECT '、' + b.Role_Name
              FROM [Sys_UserRole] a 
              LEFT JOIN [Sys_Role] b on a.UserRole_RoleID=b.Role_ID
              WHERE a.UserRole_UserID = {nameof(w.t1)}.{nameof(w.t1.User_ID)}
              FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
        "),
                    w.t1.User_CreateTime,
                    _ukid = w.t1.User_ID
                })
                .TakePage(Page, Rows, out int TotalCount)
                ;

            return await this.db.AsTableViewModelAsync(query, Page, Rows, TotalCount);
        }

        /// <summary>
        /// 新增\修改
        /// </summary>
        /// <param name="Dto"></param>
        /// <returns></returns>
        public async Task<Guid> SaveAsync(Sys_UserDto Dto)
        {
            var model = Dto.Model;
            var roleIds = Dto.RoleIds;

            try
            {
                db.AdoProvider.BeginTransaction();

                if (model.User_ID == Guid.Empty)
                {
                    model.User_Pwd = string.IsNullOrWhiteSpace(model.User_Pwd) ? "123" : model.User_Pwd; //Tools.MD5Encrypt("123");
                    model.User_ID = await db.Insert(model).SaveAsync<Guid>();
                }
                else
                {
                    //如果 密码字段为空，则不修改该密码
                    var _Success = await db.UpdateById(model)
                                        .NotMapped(w => w.User_Pwd, string.IsNullOrWhiteSpace(model.User_Pwd))
                                        .SaveAsync();
                }

                //
                if (roleIds.Count > 0)
                {
                    var _Sys_UserRoleList = await db.Query<Sys_UserRole>(w => w.t1.UserRole_UserID == model.User_ID).ToListAsync();
                    await db.Delete<Sys_UserRole>(w => w.t1.UserRole_UserID == model.User_ID).SaveAsync();
                    foreach (var item in roleIds)
                    {
                        var _Sys_UserRole = _Sys_UserRoleList.FirstOrDefault(w => w.UserRole_RoleID == item);
                        await db.Insert(new Sys_UserRole
                        {
                            UserRole_ID = _Sys_UserRole == null ? Guid.NewGuid() : _Sys_UserRole.UserRole_ID,
                            UserRole_RoleID = item,
                            UserRole_UserID = model.User_ID
                        }).SaveAsync();
                    }
                }

                db.AdoProvider.Commit();
            }
            catch (Exception)
            {
                db.AdoProvider.Rollback();
                throw;
            }

            return model.User_ID;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="Keys"></param>
        /// <returns></returns>
        public async Task DeleteAsync(List<Guid> Ids)
        {
            this.iSqlContexts = new List<ISqlContext>();

            foreach (var item in Ids)
            {
                var sysUser = await db.FindByIdAsync<Sys_User>(item);
                if (sysUser.User_IsDelete == 2) throw new MessageBox("该信息无法删除！");

                db.Delete<Sys_UserRole>(w => w.t1.UserRole_UserID == item).ToSqlContext(this.iSqlContexts);
                db.DeleteById<Sys_User>(item).ToSqlContext(this.iSqlContexts);
            }

            //此函数用于批量 sql 操作
            await db.ExecuteBatchAsync(this.iSqlContexts);
        }

        /// <summary>
        /// 加载表单 数据
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<object> LoadFormAsync(Guid Id)
        {
            var Model = await db.FindByIdAsync<Sys_User>(Id);

            var RoleIds = await db.Query<Sys_UserRole>()
                .Join<Sys_Role>(w => w.t1.UserRole_RoleID == w.t2.Role_ID)
                .Where(w => w.t1.UserRole_UserID == Id)
                .OrderByDesc(w => w.t1.UserRole_CreateTime)
                .Select(w => w.t1.UserRole_RoleID)
                .ToListAsync<Guid>()
                ;

            var AllRoleList = await db.Query<Sys_Role>()
                .OrderBy(w => w.t1.Role_Num)
                .Select(w => new { w.t1.Role_ID, w.t1.Role_Name })
                .ToSql(out string sql1)
                .ToDictionaryListAsync();

            return new { Id, Model, RoleIds, AllRoleList };
        }


        #endregion

        #region 导出 Excel

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <param name="Search"></param>
        /// <returns></returns>
        public async Task<byte[]> ExportExcel(Sys_User Search)
        {
            var tableViewModel = await this.FindListAsync(1, 999999, Search);
            return this.ExportExcelByTableViewModel(tableViewModel);
        }

        #endregion

    }
}
